package com.linjj.seckill.service.impl;

import com.linjj.seckill.domain.User;
import com.linjj.seckill.exception.GlobalException;
import com.linjj.seckill.mapper.UserMapper;
import com.linjj.seckill.redis.RedisService;
import com.linjj.seckill.redis.UserKey;
import com.linjj.seckill.service.IUserService;
import com.linjj.seckill.util.MD5Util;
import com.linjj.seckill.util.UUIDUtil;
import com.linjj.seckill.vo.CodeMsg;
import com.linjj.seckill.vo.LoginVo;
import com.linjj.seckill.vo.RegistVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Service
public class UserService implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisService redisService;
    @Override
    public int register(RegistVo registVo) {
        registVo.setSalt(MD5Util.salt);//正常情况下应该随机salt，这里写死
        registVo.setPassword(MD5Util.formToDb(registVo.getPassword(),registVo.getSalt()));
        return userMapper.insertUser(registVo);
    }

    public User getUserByPhone(String phone){
        User user = redisService.get(UserKey.id,phone,User.class);
        if(user==null){
            user = userMapper.getUserByPhone(phone);
            redisService.set(UserKey.id,phone,user);
        }
       return user;
    }
    @Override
    public boolean login(HttpServletResponse response,LoginVo loginVo) {
        if(loginVo==null){
            throw new GlobalException(CodeMsg.SERVER_ERROR);
        }
        String phone = loginVo.getPhone();
        String formPass = loginVo.getPassword();
        User user = getUserByPhone(phone);
        if(user==null){
            //手机号未注册
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
        }
        String dbSalt = user.getSalt();
        String dbPass = user.getPassword();
        if(!dbPass.equals(MD5Util.formToDb(formPass,dbSalt))){
            //密码错误
            throw new GlobalException(CodeMsg.PASSWORD_ERROR);
        }
        String token = UUIDUtil.uuid();
        addCookie(response,token,user);
        return true;
    }
    @Override
    public User getUserByToken(HttpServletResponse response,String cookieToken) {
        User user = redisService.get(UserKey.token,cookieToken,User.class);
        if(user!=null){
            addCookie(response,cookieToken,user);
        }
        return user;
    }

    @Override
    public boolean updateUser(User user,HttpServletRequest request) {
        boolean update = userMapper.updateUser(user);
        String token = getTokenFromRequest(request);
        if(update){
            User updateUser = userMapper.getUserByPhone(String.valueOf(user.getUserId()));
            redisService.set(UserKey.token,token,updateUser);
            redisService.set(UserKey.id,String.valueOf(user.getUserId()),updateUser);
        }
        return update;
    }

    @Override
    public boolean logout(HttpServletRequest request) {
        String token = getTokenFromRequest(request);
        return redisService.delete(UserKey.token,token);
    }

    private String getTokenFromRequest(HttpServletRequest request){
        String paramToken = request.getParameter(UserKey.TOKEN_NAME);
        String cookieToken = getCookieValue(request, UserKey.TOKEN_NAME);
        if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
            return null;
        }
        String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
        return token;
    }
    private String getCookieValue(HttpServletRequest request, String cookiName) {
        Cookie[]  cookies = request.getCookies();
        if(cookies == null || cookies.length <= 0){
            return null;
        }
        for(Cookie cookie : cookies) {
            if(cookie.getName().equals(cookiName)) {
                return cookie.getValue();
            }
        }
        return null;
    }

    private void addCookie(HttpServletResponse response, String token, User user) {
        redisService.set(UserKey.token,token,user);
        Cookie cookie = new Cookie(UserKey.TOKEN_NAME,token);
        cookie.setMaxAge(UserKey.token.expireSeconds());
        cookie.setPath("/");
        response.addCookie(cookie);
    }
}
